package org.wheel.plugins.starter.autoconfigure;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.wheel.plugins.toolkit.jdbc.pool.bean.DatabaseConnection;
import org.wheel.plugins.toolkit.jdbc.pool.util.DynamicJdbcPoolUtil;

import javax.sql.DataSource;

/**
 * 把官方已建好的 DataSource 吸收进工具类，避免后续重复新建
 */
public class OfficialDataSourceAbsorber implements InitializingBean, ApplicationContextAware {

    private ApplicationContext applicationContext;
    private final DynamicDataSourceProperties properties;
    private final DynamicJdbcPoolUtil util;
    private DataSource dataSource;

    public OfficialDataSourceAbsorber(DynamicDataSourceProperties properties,
                                      DynamicJdbcPoolUtil util) {
        this.properties = properties;
        this.util = util;
    }

    public OfficialDataSourceAbsorber(DataSource dataSource,
                                      DynamicDataSourceProperties properties,
                                      DynamicJdbcPoolUtil util) {
        this.properties = properties;
        this.util = util;
        this.dataSource = dataSource;   // 如果类里需要用到
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        this.applicationContext = applicationContext;
    }

    @Override
    public void afterPropertiesSet() {
        ConfigurableListableBeanFactory beanFactory =
                (ConfigurableListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();

        // 1. 吸收主数据源（官方默认 beanName = dataSource）
        DataSource primaryDs = beanFactory.getBean("dataSource", DataSource.class);
        String primaryName = StrUtil.blankToDefault(properties.getName(), properties.getDefaultName());
        absorb(primaryName, primaryDs);

        // 2. 吸收多数据源（YAML 里定义的 key 就是 beanName）
        if (MapUtil.isNotEmpty(properties.getMultiDatasource())) {
            properties.getMultiDatasource().forEach((key, conn) -> {
                if (beanFactory.containsBean(key)) {
                    DataSource ds = beanFactory.getBean(key, DataSource.class);
                    absorb(conn.getName(), ds);
                }
                // 官方没有同名 Bean → 留给兜底配置去预热
            });
        }
    }

    private void absorb(String name, DataSource dataSource) {
        DatabaseConnection conn = new DatabaseConnection();
        conn.setName(name);
        // 占位触发 computeIfAbsent
        util.getJdbcTemplate(name);
        // 用官方实例覆盖，避免后续再新建
        util.put(name, new org.springframework.jdbc.core.JdbcTemplate(dataSource));
    }
}